package cn.edu.ecut.socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.HashSet;
import java.util.Set;

public class ForthServer {
	
	private String ip = "1.0.0.99" ; // IP地址
	private int port = 9527 ; // 端口号
	
	private ServerSocket serverSocket ;
	
	private void init() {
		try {
			this.serverSocket = new ServerSocket();
		} catch ( IOException cause ) {
			throw new RuntimeException( "创建ServerSocket时发生故障" , cause );
		}
	}
	
	private void bind() {
		try {
			SocketAddress address = new InetSocketAddress( this.ip , this.port );
			serverSocket.bind( address );
		} catch ( IOException cause ) {
			throw new RuntimeException( "为创建ServerSocket实例绑定IP地址和端口时发生故障" , cause );
		}
	}
	
	public void start() {
		this.init(); // 创建ServerSocket对象
		this.bind(); // 绑定IP地址和端口
	}
	
	class ServiceThread extends Thread {
		private Socket client ; // 用于保存客户端对应的Socket对象
		public ServiceThread( Socket client ) {
			this.client = client ;
		}
		@Override
		public void run() {
			try {
				InputStream in = client.getInputStream(); // 获得可以从客户端读取数据的字节输入流
				InputStreamReader rd = new InputStreamReader( in );
				BufferedReader br = new BufferedReader( rd );
				
				String message ;
				while( ( message = br.readLine() ) != null ) {
					System.out.println( "接收到来自客户端的数据: " + message );
					forward( message ); // 调用宿主类的实例方法
					if( "byebye".equalsIgnoreCase( message ) ) {
						break ;
					}
				}
				
				br.close();
				rd.close();
				in.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	private Set<Socket> socketSet = new HashSet<>();
	
	private void forward( String message ) {
		for( Socket s : socketSet ) {
			OutputStream out;
			try {
				out = s.getOutputStream();
				PrintStream ps = new PrintStream( out );
				ps.println( "【" + message + "】"); 
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	public void service() {
		while( true ) {
			try {
				System.out.println( "正在监听客户端连接" );
				Socket socket = serverSocket.accept(); // 监听客户端连接
				socketSet.add( socket ) ; // 将 监听到的客户端Socket添加到集合中
				ServiceThread st = new ServiceThread( socket ); // 创建一个单独为该 socket 提供服务的线程
				st.start(); // 启动线程
				System.out.println( "监听到： " + socket );
			} catch ( IOException cause ) {
				throw new RuntimeException( "为创建ServerSocket实例绑定IP地址和端口时发生故障" , cause );
			} 
		}
	}
	
	public static void main(String[] args) {
		
		ForthServer ts = new ForthServer();
		
		ts.start();
		
		ts.service();
		
	}

}
